﻿using Microsoft.Xna.Framework;
using Terraria;
using Terraria.DataStructures;
using Terraria.ModLoader;
using Terraria.ModLoader.IO;
using Terraria.ID;
using HardcoreGame.Common.Cores.Logic;
using HardcoreGame.Content.Buffs;

namespace HardcoreGame.Common.Players
{
    internal class StaminaPlayer : ModPlayer
    {
        public StaminaLogic Logic { get; internal set; }
        protected override bool CloneNewInstances => false;
        public bool WillApplyExhaustion;
        public bool IsDashing;
        public bool IsJumping;
        public bool IsFlying;
        public bool HasCheckedFlying;
        private int SweatDelay;
        public override void Initialize()
        {
            Logic = new StaminaLogic(-1, false);
        }
        public override void CopyClientState(ModPlayer clone)
        {
            StaminaPlayer staminaPlayer = (StaminaPlayer)clone;
            staminaPlayer.Logic = Logic.Clone();
            staminaPlayer.WillApplyExhaustion = WillApplyExhaustion;
            staminaPlayer.IsDashing = IsDashing;
            staminaPlayer.IsJumping = IsJumping;
            staminaPlayer.IsFlying = IsFlying;
            staminaPlayer.HasCheckedFlying = HasCheckedFlying;
            staminaPlayer.SweatDelay = SweatDelay;
        }
        public override void SendClientChanges(ModPlayer clientPlayer)
        {
            StaminaPlayer staminaPlayer = (StaminaPlayer)clientPlayer;
            staminaPlayer.Logic = Logic.Clone();
            staminaPlayer.WillApplyExhaustion = WillApplyExhaustion;
            staminaPlayer.IsDashing = IsDashing;
            staminaPlayer.IsJumping = IsJumping;
            staminaPlayer.IsFlying = IsFlying;
            staminaPlayer.HasCheckedFlying = HasCheckedFlying;
            staminaPlayer.SweatDelay = SweatDelay;
        }
        public override void OnEnterWorld()
        {
            if (Player.whoAmI != Main.myPlayer)
            {
                return;
            }
            if (Player.whoAmI != Main.myPlayer)
            {
                return;
            }
            if (Main.netMode == NetmodeID.SinglePlayer)
            {
                OnSingleJoin();
            }
        }
        public override void SyncPlayer(int toWho, int fromWho, bool newPlayer)
        {
            if (Main.netMode == NetmodeID.MultiplayerClient)
            {
                if (newPlayer)
                {
                    OnClientJoin();
                    return;
                }
            }
            else if (Main.netMode == NetmodeID.Server && toWho == -1 && fromWho == Player.whoAmI)
            {
                OnServerJoin();
            }
        }
        public static void OnSingleJoin()
        {
        }
        public static void OnClientJoin()
        {
        }
        public static void OnServerJoin()
        {
        }
        public override void LoadData(TagCompound tags)
        {
            Initialize();
            int max = 100;
            bool has = true;
            if (tags.ContainsKey("Max_Stamina") && tags.ContainsKey("Has_Stamina"))
            {
                max = tags.GetInt("Max_Stamina");
                has = tags.GetBool("Has_Stamina");
            }
            Logic = new StaminaLogic(max, has);
        }
        public override void SaveData(TagCompound tag)
        {
            if (Logic != null)
            {
                tag.Add("Has_Save", true);
                tag.Add("Max_Stamina", Logic.MaxStamina);
                tag.Add("Has_Stamina", Logic.HasStaminaSet);
            }
        }
        private void ApplyDebuffs()
        {
            int buffid = ModContent.BuffType<ExhaustionBuff>();
            int duration = 160 - (int)Logic.TiredTimer;
            if (duration > 0)
            {
                Player.AddBuff(buffid, duration, true);
            }
        }
        private void ApplyExhaustionEffect()
        {
            ExhaustionBuff.ApplyMovementExhaustion(Player);
            Player.dashDelay = 1;
            Player.rocketTime = 0;
            Player.wingTime = 0f;
        }
        public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float g, ref float b, ref float a, ref bool fullBright)
        {
            if (Logic != null)
            {
                if (Logic.Stamina <= 0f)
                {
                    int num = SweatDelay - 1;
                    SweatDelay = num;
                    if (num <= 0)
                    {
                        SweatDelay = 3;
                        int width = 32;
                        int height = 16;
                        Vector2 pos;
                        pos = new(Player.position.X - Player.width / 2, Player.position.Y);
                        if (Player.gravDir < 0f)
                        {
                            pos.Y += Player.height;
                        }
                        Vector2 vel = Player.velocity;
                        vel.X += 6f - Main.rand.NextFloat() * 8f;
                        vel.Y += Main.rand.NextFloat() * -8f;
                        Dust.NewDust(pos, width, height, DustID.UnholyWater, vel.X, vel.Y, 0, default, 1f);
                    }
                }
            }
        }

        [System.Obsolete]
        public override void ModifyHurt(ref Player.HurtModifiers modifiers)
        {
            if (modifiers.DamageSource != null)
            {
                string srcReason = modifiers.DamageSource.SourceCustomReason;
                if (srcReason != null)
                {
                    modifiers.SetMaxDamage(0);
                }
            }
        }
        public override void PostHurt(Player.HurtInfo info)
        {
            float yike = info.Damage * 0.08f * 2f;
            Logic.AddStamina(Player, yike);
        }
        public override bool PreItemCheck()
        {
            bool prechecked = base.PreItemCheck();

            if (Logic != null)
            {
                if (Player.inventory[Player.selectedItem].type != ItemID.None && !Player.noItems && Player.controlUseItem && Player.itemTime <= 1)
                {
                    Logic.SetItemUseHoldDurationForStaminaDrain(36);
                }
                return prechecked;
            }
            return prechecked;
        }
        public override void PreUpdate()
        {
            if (Logic != null)
            {
                Logic.UpdateMaxStamina2(Player);
                if (!Player.dead)
                {
                    Logic.PassiveFatigueRecover(Player);
                    Logic.PassiveStaminaRegen(Player);
                    Logic.GatherPassiveStaminaDrains(Player);
                    Logic.CommitStaminaDrains(Player);
                    if (Logic.Stamina == 0f)
                    {
                        ApplyDebuffs();
                    }
                }
            }
        }
        public override void PostUpdateRunSpeeds()
        {
            if (Logic == null)
            {
                return;
            }
            if (!Player.dead)
            {
                Logic.GatherActivityStaminaDrains(Player);
                if (WillApplyExhaustion)
                {
                    ApplyExhaustionEffect();
                    WillApplyExhaustion = false;
                }
            }
        }
    }
}
